home *** CD-ROM | disk | FTP | other *** search
/ Complete Linux / Complete Linux.iso / docs / system / mail / transpor / ifmail23.z / ifmail23 / ifmail / ifcico / ttyio.c < prev    next >
Encoding:
C/C++ Source or Header  |  1994-05-03  |  5.6 KB  |  348 lines

  1. #include <unistd.h>
  2. #include <string.h>
  3. #if defined(HAS_TCP) || defined(HAS_TERM)
  4. #include <sys/types.h>
  5. #ifdef HAS_NET_ERRNO_H
  6. #include <sys/bsdtypes.h>
  7. #include <net/errno.h>
  8. #endif
  9. #endif
  10. #ifdef HAS_IOCTL_H
  11. #include <sys/ioctl.h>
  12. #endif
  13. #include <sys/socket.h>
  14. #include <fcntl.h>
  15.  
  16. #ifdef NOISEDEBUG
  17. #include <stdlib.h>
  18. #include <limits.h>
  19. #include <sys/types.h>
  20. #include <time.h>
  21. #endif
  22.  
  23. #include <stdio.h>
  24. #include <signal.h>
  25. #include <errno.h>
  26. #include "lutil.h"
  27. #include "ttyio.h"
  28.  
  29. #define PUSHMAX 8
  30.  
  31. extern int hanged_up;
  32.  
  33. int timed_out;
  34. int tty_status=0;
  35. int f_flags;
  36.  
  37. #ifdef NOISEDEBUG
  38. extern int junklevel;
  39. extern void damage(char*,int*);
  40. #endif
  41.  
  42. static int tty_wait(void);
  43. static int tty_nowait(void);
  44.  
  45. static char buf[BUFSIZ];
  46. static char *next;
  47. static int left=0;
  48.  
  49. static char pushbuf[PUSHMAX];
  50. static int pushindex;
  51.  
  52. static void almhdl(sig)
  53. int sig;
  54. {
  55.     debug(18,"timeout");
  56.     timed_out=1;
  57. }
  58.  
  59. static void get_buf(tot)
  60. int tot;
  61. {
  62.     int err;
  63.  
  64.     if (tty_status&STAT_HANGUP) return;
  65.  
  66.     timed_out=0;
  67.     signal(SIGALRM,almhdl);
  68.     alarm(tot);
  69.     left=read(0,buf,BUFSIZ);
  70.     if (left < 0) err=errno;
  71.     else err=0;
  72. #ifdef NOISEDEBUG
  73.     damage(buf,&left);
  74. #endif
  75.     alarm(0);
  76.     signal(SIGALRM,SIG_DFL);
  77.     if (hanged_up)
  78.         tty_status=STAT_HANGUP;
  79.     else if (timed_out)
  80.         tty_status=STAT_TIMEOUT;
  81.     else if (left == 0)
  82.         tty_status=STAT_EMPTY;
  83.     else if (left < 0)
  84.     {
  85.         if ((err == 0) || (err == EAGAIN))
  86.             tty_status=STAT_EMPTY;
  87.         else if ((err == EPIPE)
  88. #if defined(HAS_TCP) || defined(HAS_TERM)
  89.                     || (err == ECONNRESET)
  90. #endif
  91.                                   )
  92.             tty_status=STAT_HANGUP;
  93.         else
  94.             tty_status=STAT_ERROR;
  95.     }
  96.     else
  97.         tty_status=0;
  98.     if (tty_status & STAT_ERROR) logerr("$tty_getc error");
  99.     if (tty_status) left=0;
  100.     next=buf;
  101.     debug(19,"get_buf returning %d bytes, status=0x%02x",left,tty_status);
  102. }
  103.  
  104. int tty_ungetc(c)
  105. int c;
  106. {
  107.     if (pushindex >= PUSHMAX) return -1;
  108.     pushbuf[pushindex++]=c;
  109.     return 0;
  110. }
  111.  
  112. int tty_getc(tot)
  113. int tot;
  114. {
  115.     int c;
  116.  
  117.     if (pushindex) return pushbuf[--pushindex]&0xff;
  118.  
  119.     if (!left) get_buf(tot);
  120.     if (tty_status) c=-tty_status;
  121.     else
  122.     {
  123.         left--;
  124.         c=(*(next++))&0xff;
  125.     }
  126.     if (c < 0) debug(19,"getc return %d",c);
  127.     else debug(19,"getc return '%s'",printablec(c));
  128.     return c;
  129. }
  130.  
  131. int tty_get(str,l,tot)
  132. char *str;
  133. int l,tot;
  134. {
  135.     int got,err;
  136.  
  137.     if (pushindex >= l)
  138.     {
  139.         while (l)
  140.         {
  141.             *(str++)=pushbuf[--pushindex];
  142.             l--;
  143.         }
  144.         return 0;
  145.     }
  146.  
  147.     while (pushindex)
  148.     {
  149.         *(str++)=pushbuf[--pushindex];
  150.         l--;
  151.     }
  152.  
  153.     if (left >= l)
  154.     {
  155.         memcpy(str,next,l);
  156.         next+=l;
  157.         left-=l;
  158.         return 0;
  159.     }
  160.  
  161.     if (left > 0)
  162.     {
  163.         memcpy(str,next,left);
  164.         str+=left;
  165.         next+=left;
  166.         l-=left;
  167.         left=0;
  168.     }
  169.  
  170.     if (tty_status&STAT_HANGUP) return tty_status;
  171.  
  172.     timed_out=0;
  173.     signal(SIGALRM,almhdl);
  174.     alarm(tot);
  175.     while (l && (tty_status == 0))
  176.     {
  177.         got=read(0,str,l);
  178.         if (got < 0) err=errno;
  179.         else err=0;
  180. #ifdef NOISEDEBUG
  181.         damage(str,&got);
  182. #endif
  183.         if (hanged_up)
  184.             tty_status=STAT_HANGUP;
  185.         else if (timed_out)
  186.             tty_status=STAT_TIMEOUT;
  187.         else if (got == 0)
  188.             tty_status=STAT_EMPTY;
  189.         if (got < 0)
  190.         {
  191.             if ((err == 0) || (err == EAGAIN))
  192.                 tty_status |= STAT_EMPTY;
  193.             else if ((err == EPIPE)
  194. #if defined(HAS_TCP) || defined(HAS_TERM)
  195.                         || (err == ECONNRESET)
  196. #endif
  197.                                       )
  198.                 tty_status |= STAT_HANGUP;
  199.             else
  200.                 tty_status=STAT_ERROR;
  201.         }
  202.         else
  203.             tty_status=0;
  204.         if (tty_status & STAT_ERROR) logerr("$tty_get error");
  205.         str+=got;
  206.         l-=got;
  207.     }
  208.     alarm(0);
  209.     signal(SIGALRM,SIG_DFL);
  210.     debug(19,"tty_get %d bytes missing, status=0x%02x",l,tty_status);
  211.     return tty_status;
  212. }
  213.  
  214. int tty_putc(c)
  215. int c;
  216. {
  217.     char buf;
  218.  
  219.     if (tty_status&STAT_HANGUP) return -tty_status;
  220.     buf=c&0xff;
  221.     tty_status=0;
  222.     ttywait(1);
  223.     if (write(1,&buf,1) != 1)
  224.     {
  225.         if ((hanged_up) ||
  226.             (errno == EPIPE) 
  227. #if defined(HAS_TCP) || defined(HAS_TERM)
  228.                      || (errno == ECONNRESET)
  229. #endif
  230.                                 )
  231.             tty_status=STAT_HANGUP;
  232.         else tty_status=STAT_ERROR;
  233.     }
  234.     if (tty_status) logerr("$tty_putc status=0x%02x",tty_status);
  235.     else debug(19,"putc '%s'",printablec(c));
  236.     return -tty_status;
  237. }
  238.  
  239. int tty_put(str,l)
  240. char *str;
  241. int l;
  242. {
  243.     int written;
  244.  
  245.     if (tty_status&STAT_HANGUP) return -tty_status;
  246.     tty_status=0;
  247.     if (l <= 0) return 0;
  248.     ttywait(1);
  249.     if ((written=write(1,str,l)) != l)
  250.     {
  251.         if ((hanged_up) ||
  252.             (errno == EPIPE)
  253. #if defined(HAS_TCP) || defined(HAS_TERM)
  254.                      || (errno == ECONNRESET)
  255. #endif
  256.                                  )
  257.             tty_status=STAT_HANGUP;
  258.         else tty_status=STAT_ERROR;
  259.     }
  260.     if (tty_status)
  261.     {
  262.         int tmpfl=fcntl(1,F_GETFL,0L);
  263.         logerr("$tty_put status=0x%02x (req %d, wrote %d, fl 0%o)",
  264.                 tty_status,l,written,tmpfl);
  265.     }
  266.     else debug(19,"tty_put %d bytes",l);
  267.     return -tty_status;
  268. }
  269.  
  270. static int waitmode=1;
  271.  
  272. int ttywait(on)
  273. int on;
  274. {
  275.     int rc=0;
  276.  
  277.     if (on == waitmode) return 0;
  278.     debug(18,"setting port waitmode %s",on?"on":"off");
  279.     if (on) rc=tty_wait();
  280.     else rc=tty_nowait();
  281.     if (rc == 0) waitmode=on;
  282.     return rc;
  283. }
  284.  
  285. int tty_wait(void)
  286. {
  287.     int rc;
  288.  
  289.     if ((rc=fcntl(0,F_SETFL,f_flags & ~O_NONBLOCK)))
  290.     {
  291.         logerr("$SETFL normal ioctl error");
  292.     }
  293.     return rc;
  294. }
  295.  
  296. int tty_nowait(void)
  297. {
  298.     int rc;
  299.  
  300.     if ((rc=fcntl(0,F_SETFL,f_flags | O_NONBLOCK)))
  301.     {
  302.         logerr("$SETFL nonblock ioctl error");
  303.     }
  304.     return rc;
  305. }
  306.  
  307. #ifdef NOISEDEBUG
  308.  
  309. #ifndef RAND_MAX
  310. #ifdef INT_MAX
  311. #define RAND_MAX INT_MAX
  312. #else
  313. #define RAND_MAX 2147483647
  314. #endif
  315. #endif
  316.  
  317. void damage(buf,len)
  318. char *buf;
  319. int *len;
  320. {
  321.     long width;
  322.     int i;
  323.  
  324.     if ((junklevel == 0) || (*len == 0)) return;
  325.  
  326.     width=RAND_MAX/junklevel;
  327.     if (rand() < width)
  328.     {
  329.         if (rand() & 4)
  330.         {
  331.             debug(18,"length %d damaged - decreased (if > 1)",*len);
  332.             if ((*len) > 1) (*len)--;
  333.         }
  334.         else
  335.         {
  336.             debug(18,"length %d damaged - increased",*len);
  337.             (*len)++;
  338.         }
  339.     }
  340.     else for (i=0;i<*len;i++) if (rand() < width)
  341.     {
  342.         debug(18,"char %d of %d damaged",i,*len);
  343.         buf[i]=rand();
  344.     }
  345. }
  346.  
  347. #endif
  348.